package com.tsmti.interceptor;


import com.alibaba.fastjson.JSON;
import com.tsmti.core.common.model.AjaxJson;
import com.tsmti.core.exception.MyException;
import com.tsmti.core.util.WebUtils;
import com.tsmti.util.LogUtils;
import org.apache.shiro.authz.UnauthorizedException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.Ordered;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @Package：com.tsmti.core.interceptor
 * @Class：HibernateInterceptor
 * @Description： 自定义异常，用于处理在请求映射和请求处理过程中抛出的异常的类，都要实现HandlerExceptionResolver接口。
 *                 HandlerExceptionResolver接口有一个方法resolveException，当controller层出现异常之后就会进入到这个方法resolveException
 * @Author：zcw
 * @Date：Created in 2018/5/15 22:57
 * @Company:
 * @Version：
 * @Modified By:
 */
public class MyHandlerExceptionResoler implements HandlerExceptionResolver,Ordered {
    private static Logger logger = LoggerFactory.getLogger(MyHandlerExceptionResoler.class);

    private int order = Ordered.HIGHEST_PRECEDENCE;
    @Override
    public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) {
        //如果请求是ajax 返回json格式
        if (WebUtils.isAjax(request)) {
            try {
                AjaxJson error = null;
                response.setContentType("application/json;charset=UTF-8");
                PrintWriter writer = response.getWriter();
                //为了系统安全,只让用户看自定义异常错误信息
                if(e instanceof MyException){
                    logger.info("一个ajax请求，发生业务错误,错误内容:"+e.getMessage());
                    error = AjaxJson.fail(e.getMessage());
                    writer.write(JSON.toJSONString(error));
                }else if (e instanceof UnauthorizedException){
                    logger.info("一个ajax请求，发生系统错误,错误内容:"+e.getMessage());
                    error = AjaxJson.fail("对不起，没有权限操作!");
                    writer.write(JSON.toJSONString(error));
                } else {
                    logger.info("一个ajax请求，发生系统错误,错误内容:"+e.getMessage());
                    error =  AjaxJson.fail("系统异常,请联系技术人员!"+e.getMessage());
                    writer.write(JSON.toJSONString(error));
                }
                if(error !=null){
                    LogUtils.saveLog(request,null,e,"ajax请求，发生系统错误");
                }
                writer.flush();
                writer.close();
            } catch (IOException e1) {
                logger.error("一个ajax请求，发生系统错误,错误内容:",e);
                e1.printStackTrace();
            }
        } else {
            // 如果不是ajax，JSP格式返回
            AjaxJson result = null;
            if(e instanceof MyException){
                logger.info("一个非ajax请求，发生业务错误,错误内容:"+e.getMessage());
                result = AjaxJson.fail(e.getMessage());
                LogUtils.saveLog(request,null,e,"系统异常,发生系统错误");
            }else if (e instanceof UnauthorizedException){
                logger.info("一个ajax请求，发生系统错误,错误内容:"+e.getMessage());
                result = AjaxJson.fail("对不起，没有权限操作!");
            } else {
                logger.info("一个非ajax请求，发生系统错误,错误内容:"+e.getMessage());
                result = AjaxJson.fail("系统异常,请联系技术人员!" + e.getMessage());
                LogUtils.saveLog(request,null,e,"系统异常,发生系统错误");
            }
            //这里需要手动将异常打印出来，由于没有配置log，实际生产环境应该打印到log里面
            logger.error("系统异常信息",e);
            ModelAndView view = new ModelAndView("/error/error");
            view.addObject("error",result);
            return view;
        }
        return null;
    }

    @Override
    public int getOrder() {
        return order;
    }


    public void setOrder(int order) {
        this.order = order;
    }

}
